/**
 * Copyright 2011 ArcBees Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package vn.nichecafe.client.presenter;

import vn.nichecafe.client.CurrentUserChangedEvent;
import vn.nichecafe.client.CurrentUserChangedEvent.CurrentUserChangedHandler;
import vn.nichecafe.client.PlaceRequestChangedEvent;
import vn.nichecafe.client.PlaceRequestChangedEvent.PlaceRequestChangedHandler;

import com.google.gwt.event.shared.GwtEvent.Type;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.ChangeTabHandler;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.RequestTabsHandler;
import com.gwtplatform.mvp.client.TabContainerPresenter;
import com.gwtplatform.mvp.client.TabView;
import com.gwtplatform.mvp.client.annotations.ChangeTab;
import com.gwtplatform.mvp.client.annotations.ContentSlot;
import com.gwtplatform.mvp.client.annotations.ProxyEvent;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.annotations.RequestTabs;
import com.gwtplatform.mvp.client.proxy.AsyncCallFailEvent;
import com.gwtplatform.mvp.client.proxy.AsyncCallFailHandler;
import com.gwtplatform.mvp.client.proxy.AsyncCallStartEvent;
import com.gwtplatform.mvp.client.proxy.AsyncCallStartHandler;
import com.gwtplatform.mvp.client.proxy.AsyncCallSucceedEvent;
import com.gwtplatform.mvp.client.proxy.AsyncCallSucceedHandler;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.Proxy;
import com.gwtplatform.mvp.client.proxy.RevealContentHandler;
import com.gwtplatform.mvp.client.proxy.RevealRootContentEvent;

/**
 * The main {@link Presenter} of the application. It contains a number of tabs
 * allowing access to the various parts of the application. Tabs are refreshed
 * whenever the current user's privileges change in order to hide areas that
 * cannot be accessed.
 * 
 * @author Christian Goudreau
 * @author Philippe Beaudoin
 */
public class MainPagePresenter
		extends
		TabContainerPresenter<MainPagePresenter.MyView, MainPagePresenter.MyProxy>
		implements CurrentUserChangedHandler, PlaceRequestChangedHandler,
		AsyncCallStartHandler, AsyncCallFailHandler, AsyncCallSucceedHandler {

	/**
	 * {@link MainPagePresenter}'s proxy.
	 */
	@ProxyStandard
	public interface MyProxy extends Proxy<MainPagePresenter> {
	}

	/**
	 * {@link MainPagePresenter}'s view.
	 */
	public interface MyView extends TabView {
		void refreshTabs();

		void setTopMessage(String string);
	}

	/**
	 * This will be the event sent to our "unknown" child presenters, in order
	 * for them to register their tabs.
	 */
	@RequestTabs
	public static final Type<RequestTabsHandler> TYPE_RequestTabs = new Type<RequestTabsHandler>();

	/**
	 * Fired by child proxie's when their tab content is changed.
	 */
	@ChangeTab
	public static final Type<ChangeTabHandler> TYPE_ChangeTab = new Type<ChangeTabHandler>();

	/**
	 * Use this in leaf presenters, inside their {@link #revealInParent} method.
	 */
	@ContentSlot
	public static final Type<RevealContentHandler<?>> TYPE_SetTabContent = new Type<RevealContentHandler<?>>();
	
	private final PlaceManager placeManager;

	@Inject
	public MainPagePresenter(final EventBus eventBus, final MyView view,
			final MyProxy proxy, PlaceManager placeManager) {
		super(eventBus, view, proxy, TYPE_SetTabContent, TYPE_RequestTabs,
				TYPE_ChangeTab);
		this.placeManager = placeManager;
	}
	
	@Override
	protected void revealInParent() {
		RevealRootContentEvent.fire(this, this);
	}

	@ProxyEvent
	@Override
	public void onCurrentUserChanged(CurrentUserChangedEvent event) {
		getView().refreshTabs();
	}

	@ProxyEvent
	@Override
	public void onAsyncCallStart(AsyncCallStartEvent event) {
		getView().setTopMessage("Loading...");
	}

	@ProxyEvent
	@Override
	public void onAsyncCallFail(AsyncCallFailEvent event) {
		getView().setTopMessage("Oops, something went wrong...");
	}

	@ProxyEvent
	@Override
	public void onAsyncCallSucceed(AsyncCallSucceedEvent event) {
		getView().setTopMessage(null);
	}
	
	@ProxyEvent
	@Override
	public void onPlaceRequestChanged(PlaceRequestChangedEvent event) {
		placeManager.revealPlace(event.getPlaceRequest());
	}
}
